package com.sky.aspects;

import com.sky.anotation.AllFull;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

//填充公共字段
@Slf4j
@Aspect
@Component
public class AutoFullAspect {

	//使用注解设置切入点
	@Before("@annotation(com.sky.anotation.AllFull)")
	void before(JoinPoint joinPoint) {
		log.info("开始自动填充字段...");
		//获取方法签名
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		//获取方法
		Method method = signature.getMethod();
		log.info("获取方法{}", method.getName());
		//获取切入点参数,针对切入点不是方法
		Object[] args = joinPoint.getArgs();
		log.info("参数类型{}", args[0].getClass().getName());
		//获取方法得到注解
		AllFull allFull = method.getAnnotation(AllFull.class);
		//判断填充字段类型
		OperationType type = allFull.value();
		log.info("字段类型{}", type);
		try
		{
			if (type == OperationType.INSERT)
			{
				fullCreate(args[0]);
				fullUpdate(args[0]);
			} else if (type == OperationType.UPDATE)
			{
				fullUpdate(args[0]);
			}
		}  catch (InvocationTargetException e)
		{
			throw new RuntimeException(e);
		} catch (IllegalAccessException e)
		{
			throw new RuntimeException(e);
		} catch (NoSuchMethodException e)
		{
			throw new RuntimeException(e);
		}
	}

	/**
	 * 填充创建字段
	 * @param object
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 */
	void fullCreate(Object object) throws IllegalAccessException,NoSuchMethodException, InvocationTargetException {
		//获取设置参数类型方法
		Method setCreateTime = object.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
		Method setCreateUser = object.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
		//暴力破解
		setCreateTime.setAccessible(true);
		setCreateUser.setAccessible(true);
		//设置参数
		setCreateTime.invoke(object, LocalDateTime.now());
		setCreateUser.invoke(object, BaseContext.getCurrentId());
	}

	/**
	 * 填充更新字段
	 * @param object
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 */
	void fullUpdate(Object object) throws IllegalAccessException,NoSuchMethodException, InvocationTargetException {
		//获取设置参数类型方法
		Method setUpdateTime = object.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
		Method setUpdateUser = object.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
		//暴力破解
		setUpdateUser.setAccessible(true);
		setUpdateTime.setAccessible(true);
		//设置参数
		setUpdateTime.invoke(object, LocalDateTime.now());
		setUpdateUser.invoke(object, BaseContext.getCurrentId());
	}
}
